package org.hackystat.sdsa.analyzer.model.rules;

import jess.Batch;
import jess.Fact;
import jess.QueryResult;
import jess.RU;
import jess.Rete;
import jess.Value;
import jess.ValueVector;

import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertEquals;

/**
 * Test JESS rule definition for episode.
 * 
 * @author Hongbing Kou
 *
 */
public class TestActivityTemplate {
  /** Rete engine. */
  private Rete engine;
  /**
   * Sets up rete network.
   * 
   * @throws Exception If error while setting up datas.
   */
  @Before public void setUp() throws Exception {
    this.engine = new Rete();
    Batch.batch("/org/hackystat/sdsa/analyzer/model/rules/ActivityTemplate.clp", 
        this.engine);
    Batch.batch("/org/hackystat/sdsa/analyzer/model/rules/EpisodeTemplate.clp", 
        this.engine);
  }
  
  /**
   * Test whether we can assert actions into JESS working memory.
   * 
   * @throws Exception Exception will be thrown if there is failure message.
   */
  public void untestActions() throws Exception {
    // Add test method
    /*UnaryRefactorAction unaryAction = new UnaryRefactorAction(this.clock, this.testFile);
    unaryAction.setOperator(RefactorOperator.ADD);
    unaryAction.setSubjectType(RefactorSubjectType.METHOD);
    unaryAction.setSubjectName("void testEquilateral()");
    unaryAction.assertJessFact(1, engine);
    
    // Edit on test
    EditAction editAction = new UnitTestEditAction(this.clock, this.testFile, 123);
    editAction.assertJessFact(2, engine);

    // Compile error on test
    CompilationAction compilationAction = new CompilationAction(this.clock, this.testFile);
    compilationAction.setErrorMessage("Unknown data type");
    compilationAction.assertJessFact(3, engine);

    // Work on production code
    editAction = new ProductionEditAction(this.clock, this.productionFile, 200);
    editAction.assertJessFact(4, engine);

    // Unit test failue
    UnitTestAction unitTestAction = new UnitTestAction(this.clock, this.testFile); 
    unitTestAction.setFailureMessage("Failed to import");
    unitTestAction.assertJessFact(5, engine);
 
    // Edit on prodction code
    editAction = new ProductionEditAction(this.clock, this.productionFile, 199);
    editAction.assertJessFact(6, engine);

    // Unit test pass
    unitTestAction = new UnitTestAction(this.clock, this.testFile); 
    unitTestAction.assertJessFact(7, engine);
    */
  }
  

  /**
   * Tests classifier on standard TDD iteration.
   * 
   * @throws Exception If failed while testing
   */
  @Test public void testTDDEpisodeCategory1() throws Exception {
    engine.reset();
    
    Fact f = new Fact("episode", engine);
    f.setSlotValue("category", new Value("regression", RU.STRING));
    f.setSlotValue("type", new Value("1", RU.STRING));
    
    this.engine.assertFact(f);
    engine.run();
    
    QueryResult result = engine.runQueryStar("episode-classification-query", new ValueVector());
    assertTrue("Type 1 TDD episode can be classified", result.next());
    
    assertEquals("Test TDD type 1 episode category name", "regression", result.getString("cat"));
    assertEquals("Test TDD type 1 episode cateory type", "1", result.getString("tp")); 
  }
}
